package com.jyxd.web.service.assessment.basic;

import com.jyxd.web.dao.basic.MedOrderExecDao;
import com.jyxd.web.data.basic.MedOrderExec;
import com.jyxd.web.data.basic.MedOrderExecRecord;
import com.jyxd.web.data.user.User;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.jyxd.web.util.DateUtil.yyyyMMddHHmmssSdfToString;

@Service("medOrderExecService")
@Transactional
public class MedOrderExecService {

    @Autowired
    private MedOrderExecDao medOrderExecDao;
    @Autowired
    private MedOrderExecRecordService medOrderExecRecordService;


    public boolean insert(MedOrderExec medOrderExec) {
        return medOrderExecDao.insert(medOrderExec);
    }

    public boolean deleteByCreateTime(Map<String, Object> map) {
        return medOrderExecDao.deleteByCreateTime(map);
    }

    public boolean update(MedOrderExec medOrderExec) {
        return medOrderExecDao.update(medOrderExec);
    }

    public boolean insertBatch(List<MedOrderExec> list) {
        return medOrderExecDao.insertBatch(list);
    }

    public MedOrderExec queryData(String id) {
        return medOrderExecDao.queryData(id);
    }

    public List<MedOrderExec> queryList(Map<String, Object> map) {
        return medOrderExecDao.queryList(map);
    }

    public int queryNum(Map<String, Object> map) {
        return medOrderExecDao.queryNum(map);
    }

    /**
     * 查询所有医嘱对象列表
     *
     * @param map
     * @return
     */
    public List<MedOrderExec> queryMedOrderExecList(Map<String, Object> map) {
        return medOrderExecDao.queryMedOrderExecList(map);
    }

    /**
     * 查询所有医嘱对象列表
     *
     * @param map
     * @return
     */
    public List<MedOrderExec> queryByCreateTime(Map<String, Object> map) {
        return medOrderExecDao.queryByCreateTime(map);
    }

    /**
     * 从his系统视图查询所有医嘱执行信息
     *
     * @return
     */
    public List<Map<String, Object>> getMedOrderExecByHis(Map<String, Object> map) {
        return null;
    }

    public List<Map<String, Object>> getList(Map<String, Object> map) {
        return medOrderExecDao.getList(map);
    }

    public int getNum(Map<String, Object> map) {
        return medOrderExecDao.getNum(map);
    }

    /**
     * 根据医嘱第三方主键id查询医嘱
     *
     * @param orderCode
     * @return
     */
    public MedOrderExec queryDataByOrderCode(String orderCode) {
        return medOrderExecDao.queryDataByOrderCode(orderCode);
    }

    /**
     * 根据患者id和医嘱内容查询医嘱
     *
     * @return
     */
    public List<MedOrderExec> queryDataByPatientIdAndOrderName(Map<String, Object> map) {
        return medOrderExecDao.queryDataByPatientIdAndOrderName(map);
    }

    /**
     * 根据患者id和主医嘱code查询副医嘱
     *
     * @return
     */
    public List<MedOrderExec> queryDataByOrderSubNo(Map<String, Object> map) {
        return medOrderExecDao.queryDataByOrderSubNo(map);
    }

    public List<MedOrderExec> queryDataByOrderSubNo(MedOrderExec medOrderExec) {
        Map<String, Object> codeMap = new HashMap<String, Object>();
        codeMap.put("patientId", medOrderExec.getPatientId());
        codeMap.put("orderNo", medOrderExec.getOrderNo());
//        codeMap.put("drugType", 1);
        return queryDataByOrderSubNo(codeMap);
    }

    /**
     * 根据父医嘱查询子遗嘱信息
     *
     * @return
     */
    public List<MedOrderExec> querySonOrderList(Map<String, Object> map) {
        return medOrderExecDao.querySonOrderList(map);
    }

    /**
     * 记录医嘱同步状态 (累计加 1)
     *
     * @param medOrderExec
     * @return
     */
    public int calculateIsSync(MedOrderExec medOrderExec) {
        if (Objects.isNull(medOrderExec))
            return 0;
        if (Objects.isNull(medOrderExec.getIsSync()))
            return 1;
        return medOrderExec.getIsSync() + 1;
    }

    /**
     * 医嘱使用记录
     */
    public void orderRecord(String orderId, User user, String dataTime) {
        ArrayList<String> ordersList=new ArrayList<String>();
        if(orderId.contains(",")){
            String[] orders = orderId.split(",");
            ordersList = new ArrayList(Arrays.asList(orders));
        }else{
            ordersList.add(orderId);
        }
        for (String ordersId : ordersList) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id", ordersId);
            try {
                //根据医嘱主键查询医嘱列表
                List<MedOrderExec> list = queryList(map);
                if (CollectionUtils.isEmpty(list)) {
                    return;
                }
                //根据主医嘱ordercode 查询此条主医嘱下的所有副医嘱
                List<MedOrderExec> medOrderExecsList = queryDataByOrderSubNo(list.get(0));
                for (MedOrderExec medOrderExec : medOrderExecsList) {
                    String frequency = medOrderExec.getFrequency();
                    if (StringUtils.isEmpty(frequency)) {
                        saveMedOrderExecRecord(medOrderExec, dataTime, user);
                    }
                    if (frequency.contains("(") && frequency.contains(")")) {
                        frequency = subString(frequency, "(", ")");//频率code
                    }
                    switch (frequency) {
                        case "1601726"://每周两次(1601726)
                        case "每周两次":
                        case "9"://隔日一次(9)
                        case "隔日一次":
                        case "36486"://每周一次(36486)
                        case "每周一次":
                            String startTime = yyyyMMddHHmmssSdfToString(medOrderExec.getDefaultTimePoint());//医嘱开始时间
                            Date frequencyEndTimeDate = medOrderExec.getFrequencyEndTime();
                            String frequencyEndTime = yyyyMMddHHmmssSdfToString(Objects.isNull(frequencyEndTimeDate) ? new Date() : frequencyEndTimeDate);//医嘱结束时间
                            List<String> betweenDates = getBetweenDates(startTime, frequencyEndTime);//获取开始结束时间内所有日期
                            if (CollectionUtils.isEmpty(betweenDates)) {
                                break;
                            }
                            for (String betweenTime : betweenDates) {
                                //插入医嘱记录表
                                MedOrderExecRecord medOrderExecRecord = medOrderExecRecordService.queryByDateAndMedId(medOrderExec.getId(), betweenTime);
                                if (Objects.isNull(medOrderExecRecord)) {
                                    medOrderExecRecordService.insert(medOrderExec, betweenTime, user);
                                    continue;
                                }
                                if (Objects.isNull(medOrderExecRecord.getSyncCount()))
                                    medOrderExecRecord.setSyncCount(1);
                                else
                                    medOrderExecRecord.setSyncCount(medOrderExecRecord.getSyncCount() + 1);
                                medOrderExecRecordService.update(medOrderExecRecord);
                            }
                            break;
                        default:
                            //插入医嘱记录表
                            saveMedOrderExecRecord(medOrderExec, dataTime, user);
                            break;
                    }
                }
            } catch (
                    Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 新增医嘱记录
     *
     * @param medOrderExec
     * @param dataTime
     * @param user
     * @throws ParseException
     */
    private void saveMedOrderExecRecord(MedOrderExec medOrderExec, String dataTime, User user) throws ParseException {
        MedOrderExecRecord medOrderExecRecord = medOrderExecRecordService.queryByDateAndMedId(medOrderExec.getId(), dataTime);
        if (Objects.isNull(medOrderExecRecord)) {
            medOrderExecRecordService.insert(medOrderExec, dataTime, user);
        } else {
            if (Objects.isNull(medOrderExecRecord.getSyncCount()))
                medOrderExecRecord.setSyncCount(1);
            else
                medOrderExecRecord.setSyncCount(medOrderExecRecord.getSyncCount() + 1);
            medOrderExecRecordService.update(medOrderExecRecord);
        }
    }

    /**
     * 获取两个日期之间的所有日期
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return List集合
     */

    private static List<String> getBetweenDates(String startDate, String endDate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> list = new ArrayList<String>(); //保存日期的集合
        Date date_start = sdf.parse(startDate);
        Date date_end = sdf.parse(endDate);
        Date date = date_start;
        Calendar cd = Calendar.getInstance();//用Calendar 进行日期比较判断
        while (date.getTime() <= date_end.getTime()) {
            list.add(sdf.format(date));
            cd.setTime(date);
            cd.add(Calendar.DATE, 1);//增加一天 放入集合
            date = cd.getTime();
        }
        return list;

    }

    /**
     * 截取字符串str中指定字符 strStart、strEnd之间的字符串
     *
     * @return
     */
    public static String subString(String str, String strStart, String strEnd) {

        /* 找出指定的2个字符在 该字符串里面的 位置 */
        int strStartIndex = str.indexOf(strStart);
        int strEndIndex = str.indexOf(strEnd);
        /* 开始截取 */
        String result = str.substring(strStartIndex, strEndIndex).substring(strStart.length());
        return result;
    }

    /**
     * 通过orderIds查询
     * @param idList
     * @return
     */
    public List<MedOrderExec> queryListByOrderIds(List<String> idList) {
        return medOrderExecDao.queryListByOrderIds(idList);
    }
    /**
     * 根据患者id和医嘱名称查询唯一的医嘱时间
     */
    public Date queryDataByPatientName(String patientId) {
        Date orderDate=null;
        Map<String, Object> codeMap = new HashMap<String, Object>();
        codeMap.put("patientId",patientId);
        //todo 判断是神经内科还是重症
        codeMap.put("orderName", "重症医学科一般护理常规");
        codeMap.put("status", 1);
        List<MedOrderExec> medOrderExecs = medOrderExecDao.queryDataByPatientIdAndOrderName(codeMap);
        if(medOrderExecs!=null && medOrderExecs.size()>0){
            orderDate= medOrderExecs.get(0).getDefaultTimePoint();
        }
        return  orderDate;
    }
}
